﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Happy.Domain
{
    /// <summary>
    /// 仓储接口，这是一个标记接口。
    /// </summary>
    public interface IRepository
    {
    }

    /// <summary>
    /// 泛型仓储接口。
    /// </summary>
    /// <remarks>
    /// 聚合状态：
    /// <list type="number">
    ///     <item>transient：实例存在于内存中，但不存在于工作单元和数据库中。</item>
    ///     <item>persistent in database：实例存在于数据库中。</item>
    ///     <item>persistent in unitofwork：实例存在于工作单元中。</item>
    ///     <item>detached：实例存在于内存和数据库中，但不存在于工作单元中。</item>
    /// </list>
    /// 合法转换：
    /// <list type="number">
    ///     <item>transient > Save -> persistent in unitofwork，Flush时会生成Insert Sql，场景：从UI层创建实例，执行创建。</item>
    ///     <item>detached -> Update -> persistent in unitofwork，Flush时会生成Update Sql，场景：从UI层重建实例，执行修改（支持离线乐观并发）。</item>
    ///     <item>detached -> Delete -> persistent in unitofwork，Flush时会生成Delete Sql，场景：从UI层重建实例，删除记录。</item>
    ///     <item>detached -> Merge -> persistent in unitofwork，Flush时会生成Update Sql，场景：从UI层重建实例，合并到从数据库重建的实例，执行修改（不支持离线乐观并发）。</item>
    ///     <item>persistent in unitofwork -> Evict -> detached，Flush时不会生成Sql，场景：将实例从当前工作单元脱钩，添加到另一个工作单元。</item>
    ///     <item>persistent in unitofwork -> Delete -> persistent in unitofwork，Flush时会生成Delete Sql，场景：从数据库重建实例，删除记录。</item>
    ///     <item>persistent in database -> Load -> persistent in unitofwork，从数据库重建实例。</item>
    ///     <item>persistent in database -> Refresh -> persistent in unitofwork，从数据库刷新实例，场景：使用存储过程修改了一个实例，使用此方法重新刷新一下。</item>
    /// </list>
    /// </remarks>
    public interface IRepository<TAggregateRoot, TId> : IRepository
        where TAggregateRoot : IAggregateRoot<TId>
    {
        /// <summary>
        /// 判断<paramref name="item"/>是否 persistent in unitofwork。
        /// </summary>
        bool Contains(TAggregateRoot item);

        /// <summary>
        /// transient > Save -> persistent in unitofwork，Flush时会生成Insert Sql，场景：从UI层创建实例，执行创建。
        /// </summary>
        void Save(TAggregateRoot item);

        /// <summary>
        /// detached -> Update -> persistent in unitofwork，Flush时会生成Update Sql，场景：从UI层重建实例，执行修改（支持离线乐观并发）。
        /// </summary>
        void Update(TAggregateRoot item);

        /// <summary>
        /// 执行如下两种转换：
        /// <list type="number">
        ///     <item>detached -> Delete -> persistent in unitofwork，Flush时会生成Delete Sql，场景：从UI层重建实例，删除记录。</item>
        ///     <item>persistent in unitofwork -> Delete -> persistent in unitofwork，Flush时会生成Delete Sql，场景：从数据库重建实例，删除记录。</item>
        /// </list>
        /// </summary>
        void Delete(TAggregateRoot item);

        /// <summary>
        /// detached -> Merge -> persistent in unitofwork，Flush时会生成Update Sql，场景：从UI层重建实例，合并到从数据库重建的实例，执行修改（不支持离线乐观并发）。
        /// </summary>
        void Merge(TAggregateRoot item);

        /// <summary>
        /// persistent in unitofwork -> Detach -> detached，Flush时不会生成Sql，场景：将实例从当前工作单元脱钩，添加到另一个工作单元。
        /// </summary>
        void Detach(TAggregateRoot item);

        /// <summary>
        /// detached -> Detach -> persistent in unitofwork，Flush时不会生成Sql，场景：将实例从UI层重建，挂钩到工作单元。
        /// </summary>
        void Attach(TAggregateRoot item);

        /// <summary>
        /// persistent in database -> Load -> persistent in unitofwork，从数据库重建实例。
        /// </summary>
        TAggregateRoot Load(TId id);

        /// <summary>
        /// persistent in database -> Refresh -> persistent in unitofwork，从数据库刷新实例，场景：使用存储过程修改了一个实例，使用此方法重新刷新一下。
        /// </summary>
        void Refresh(TAggregateRoot item);

        /// <summary>
        /// 所属的工作单元。
        /// </summary>
        IUnitOfWork UnitOfWork { get; }
    }
}
